package ui {
	import jazztures.Jazztures;
	import jazztures.events.SkeletonEvent;
	import jazztures.objects.Skeleton;
	import jazztures.utils.GeometryUtils;

	import flash.geom.Vector3D;
	
	public class KinectWheelController {
		public static const TWO_HANDS:String = "two_hands";
		public static const ONE_HAND:String = "one_hand";
		public static const NO_HANDS : String = "no_hands";

		private var kinect : Jazztures;
		private var skeleton : Skeleton;
		private var middlePoint:Vector3D;
		private var currentSkeleton:int = -1;

		public function KinectWheelController(){
			kinect = new Jazztures();
			kinect.connect();
			
			kinect.addEventListener(SkeletonEvent.ADD_SKELETON, skeletonListener);
			kinect.addEventListener(SkeletonEvent.UPDATE_SKELETON, skeletonListener);
			kinect.addEventListener(SkeletonEvent.REMOVE_SKELETON, skeletonListener);
		}

		private function skeletonListener(event : SkeletonEvent) : void {
			switch(event.type){
				case SkeletonEvent.ADD_SKELETON:
					currentSkeleton = event.id;
					break;
				
				case SkeletonEvent.REMOVE_SKELETON:
					currentSkeleton = -1;
					break;
					
				case SkeletonEvent.UPDATE_SKELETON:
					if(currentSkeleton<0) skeletonListener(new SkeletonEvent(SkeletonEvent.ADD_SKELETON, event.id, null));
					skeleton = event.skeleton;
					break;
			}
		}
		
		public function get isTracking():Boolean{
			return currentSkeleton>-1;
		}
		
		public function get drivingStyle():String{
			if(!skeleton) return NO_HANDS;
			
			var leftShoulderToElbow:Number = to360(GeometryUtils.getYaw(skeleton.leftShoulder.vector3D, skeleton.leftElbow.vector3D, true, "z", "y"));
			var leftElbowToHand:Number = to360(GeometryUtils.getYaw(skeleton.leftElbow.vector3D, skeleton.leftHand.vector3D, true, "z", "y"));
			var rightShoulderToElbow:Number = to360(GeometryUtils.getYaw(skeleton.rightShoulder.vector3D, skeleton.rightElbow.vector3D, true, "z", "y"));
			var rightElbowToHand:Number = to360(GeometryUtils.getYaw(skeleton.rightElbow.vector3D, skeleton.rightHand.vector3D, true, "z", "y"));
						
			if(leftShoulderToElbow >250 && leftShoulderToElbow < 280 &&
			leftElbowToHand > 250 && leftElbowToHand < 280 && 
			rightShoulderToElbow > 250 && rightShoulderToElbow < 280 &&
			rightElbowToHand > 250 && rightElbowToHand < 280){
				return TWO_HANDS;
			}else if(leftShoulderToElbow >250 && leftShoulderToElbow < 280 &&
			leftElbowToHand > 250 && leftElbowToHand < 280){
				return ONE_HAND;
			}else{
				return NO_HANDS;
			}
		}
		
		public function get wheelRotation():Number{
			var style:String = drivingStyle;
			if(style == KinectWheelController.TWO_HANDS){
				middlePoint = GeometryUtils.getMiddlePoint(skeleton.leftHand.vector3D, skeleton.rightHand.vector3D);
				return (to360(GeometryUtils.getYaw(skeleton.leftHand.vector3D, skeleton.rightHand.vector3D, true, "y", "x")-180)-180)/180*5;
			}else if(style == KinectWheelController.ONE_HAND){
				return (to360(GeometryUtils.getYaw(skeleton.leftHand.vector3D, middlePoint ? middlePoint : skeleton.neck.vector3D, true, "y", "x")-180)-180)/180*5;
			}else{
				middlePoint = null;
				return 0;
			}
		}

		private function to360(angle:Number) : Number {
			angle < 0 ? angle = 360 + angle : null;
			return angle%360;
		}
		
		public function get acceleration():Number{
			if(skeleton) if(skeleton.leftFoot.x - skeleton.leftKnee.x < 0) return 0;
			if(skeleton) return Math.max((skeleton.leftFoot.z - skeleton.rightFoot.z)/100, 0);
			return 0;
		}
		
		public function get isBraking():Boolean{
			if(skeleton) return (skeleton.leftFoot.x - skeleton.leftKnee.x < 0);
			return false;
		}
		
		public function get leftShoulder():Vector3D{
			if(skeleton) return skeleton.leftShoulder.vector3D;
			return new Vector3D();
		}
		
		public function get leftElbow():Vector3D{
			if(skeleton) return skeleton.leftElbow.vector3D;
			return new Vector3D();
		}
		
		public function get leftHand():Vector3D{
			if(skeleton) return skeleton.leftHand.vector3D;
			return new Vector3D();
		}
		
		public function get rightShoulder():Vector3D{
			if(skeleton) return skeleton.rightShoulder.vector3D;
			return new Vector3D();
		}
		
		public function get rightElbow():Vector3D{
			if(skeleton) return skeleton.rightElbow.vector3D;
			return new Vector3D();
		}
		
		public function get rightHand():Vector3D{
			if(skeleton) return skeleton.rightHand.vector3D;
			return new Vector3D();
		}
		
		public function get neck():Vector3D{
			if(skeleton) return skeleton.neck.vector3D;
			return new Vector3D();
		}
	}
}
